﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Diagnostics;
using System.ServiceProcess;


namespace Informant.Services.Windows
{
	[RunInstaller(true)]
	public partial class ProjectInstaller : Installer
	{
		#region Fields

		ServiceController _informantWinServiceController;
		TimeSpan _statusChangeWaitLimit;

		#endregion

		#region Construction

		/// <summary>
		/// Initializes a new instance of the <see cref="ProjectInstaller"/> class.
		/// </summary>
		public ProjectInstaller()
		{
			InitializeComponent();
			_informantWinServiceController = new ServiceController("InformantWinService");
			_statusChangeWaitLimit = new TimeSpan(0, 0, 10);
		}

		#endregion

		#region Overridden Methods

		/// <summary>
		/// Raises the <see cref="E:System.Configuration.Install.Installer.AfterInstall"/> event.
		/// </summary>
		/// <param name="savedState">An <see cref="T:System.Collections.IDictionary"/> that contains the state of the computer after all the installers contained in the <see cref="P:System.Configuration.Install.Installer.Installers"/> property have completed their installations.</param>
		protected override void OnAfterInstall(IDictionary savedState)
		{
			base.OnAfterInstall(savedState);
			StartService(_informantWinServiceController);

		}
		/// <summary>
		/// Raises the <see cref="E:System.Configuration.Install.Installer.BeforeUninstall"/> event.
		/// </summary>
		/// <param name="savedState">An <see cref="T:System.Collections.IDictionary"/> that contains the state of the computer before the installers in the <see cref="P:System.Configuration.Install.Installer.Installers"/> property uninstall their installations.</param>
		protected override void OnBeforeUninstall(IDictionary savedState)
		{
			StopService(_informantWinServiceController);
			base.OnBeforeUninstall(savedState);
		}

		#endregion

		#region Private Methods

		/// <summary>
		/// Starts the service.
		/// </summary>
		/// <param name="serviceController">The service controller.</param>
		private void StartService(ServiceController serviceController)
		{
			try
			{
				serviceController.Start();
				serviceController.WaitForStatus(ServiceControllerStatus.Running, _statusChangeWaitLimit);
			}
			catch (InvalidOperationException ex)
			{
				// TODO: Log error
				
				// Force Rollback
				throw ex;
			}
		}
		/// <summary>
		/// Stops the service.
		/// </summary>
		/// <param name="serviceController">The service controller.</param>
		private void StopService(ServiceController serviceController)
		{
			try
			{
				serviceController.Stop();
				serviceController.WaitForStatus(ServiceControllerStatus.Stopped, _statusChangeWaitLimit);
			}
			catch (InvalidOperationException ex)
			{
				if (serviceController.Status != ServiceControllerStatus.Stopped)
				{
					// TODO: Log error

					// Force Rollback
					throw ex;
				}
			}
		}

		#endregion
	}
}
